/*
 * ChatView.java
 */
package chat.client;

import chat.common.*;
import chat.client.resources.*;
//import chat.
import java.*;
import java.awt.Dimension;
import java.awt.event.*;

import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.InputMap;
import javax.swing.*;

//import org.xnap.commons.gui.CloseableTabbedPane;
import javax.swing.JTabbedPane;


import java.net.*;
import java.io.*;
import java.util.*;

/**
 * The application's main frame.
 */
public class ChatView extends FrameView {

    /**
     * Entete des messages
     */
    private Communication communication = null; // on cree un thread qui s'occupera de recevoir les entree venant du server
    private static HashSet<TextTab> vectTextTab = new HashSet();
    private static InfoTree infoTree;
    private JFrame mainFrame;
    private boolean ackDialog;
    private int numeroPort = 51111; // @Todo deplacer
    private Vector<SendFile> vectSendFile = new Vector();
    private DownloadPanel downloadPanel = null;

    /**
     * InputMap pour les racourcie clavier
     * CTRL+Q > quit
     * CTRL+W > closeTab
     * ALT+PageUp/ ALT+PageDown > changer onglet
     * @param rootPane
     */
    private void configureRootPane(JRootPane rootPane) {

        InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK), "closeApp");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK), "closeTab");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, InputEvent.ALT_MASK), "switchTabUP");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, InputEvent.ALT_MASK), "switchTabDOWN");

        rootPane.getActionMap().put(
                "closeApp",
                new AbstractAction("closeApp") {

                    public void actionPerformed(ActionEvent actionEvent) {
                        closeApplication();
                    }
                });
        rootPane.getActionMap().put(
                "closeTab",
                new AbstractAction("closeTab") {

                    public void actionPerformed(ActionEvent actionEvent) {
                        TextTab tab = currentTab();
                        if (tab != null && !tab.getIdTab().equals("systemPanel")) {
                            closeTab(tab);
                        }
//                        addDownloadProgressBar("rien");
                    }
                });
        rootPane.getActionMap().put(
                "switchTabUP",
                new AbstractAction("switchTabUP") {

                    public void actionPerformed(ActionEvent actionEvent) {
                        System.out.println("up");
                        switchTab("UP");
                    }
                });
        rootPane.getActionMap().put(
                "switchTabDOWN",
                new AbstractAction("switchTabDOWN") {

                    public void actionPerformed(ActionEvent actionEvent) {
                        System.out.println("down");
                        switchTab("DOWN");
                    }
                });
    }

    /**
     * Constructeur de la clesse ChatView
     * Initialisation des composant graphique
     * Creation de systemPanel
     * Configuration de bouton ...
     * @param app
     */
    public ChatView(SingleFrameApplication app) {
        super(app);
        this.ackDialog = false; // for reponse from dialog box;

        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBarre.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {

            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBarre.setVisible(true);
                    progressBarre.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBarre.setVisible(false);
                    progressBarre.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String) (evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer) (evt.getNewValue());
                    progressBarre.setVisible(true);
                    progressBarre.setIndeterminate(false);
                    progressBarre.setValue(value);
                }
            }
        });

        mainFrame = ChatApp.getApplication().getMainFrame();
        mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        mainFrame.setTitle("Chat seb-jul");
        mainFrame.setSize(500, 300);
        Dimension dim = new Dimension(300, 200);
        mainFrame.setMinimumSize(dim);
        /*
         * creation de la keymap
         */
        configureRootPane(statusPanel.getRootPane());
        /**
         * on init le panel d'information, et on l'ajoute au vecteur
         */
        TextTab systemPanel = new TextTab(this, null, "systemPanel");
        tabPanel.addTab("System Panel", null, systemPanel, "System panel information");

        systemPanel.setEnsable(false);
        vectTextTab.add(systemPanel);

        infoTree = new InfoTree(this, null);
        infoPanel.add(infoTree);
        infoPanel.setVisible(true);
        infoTree.setEnabled(true);
        infoTree.setVisible(true);

        connectionMenuItem.setEnabled(true);
        deconnectionMenuItem.setEnabled(false);
        newChannelMenuItem.setEnabled(false);
        fileMenuItem.setEnabled(false);

        this.writeInfo("Hello boy !");
    }

    /**
     * Initialisation de la Connection pour creer une communication
     * Si la connection echou, on ecrit un message dans le SystemPanel
     * Si le message du server est de type ERROR_CONNECTION, on annule tout
     * Sinon, c'estok et on fini en configurant les elements graphiques
     * @param login Identifiant sur le server et pour les autres utilisateurs
     * @param host Adresse de la machine (IP, ou dns)
     * @param port Numero de port de la connection
     */
    public void initCommunication(String login, String host, int port) {
        // TODO code application logic here
        try {

            this.communication = new Communication(this, login, host, port);

            /*
             * on recois la reponse du serveur
             */
            Message mess = new Message();
            mess.readMessage(communication.getEntree());
            if (mess.getType() == Message.ERROR_CONNECTION) {
                // on l'ecrit dans le tab d'information du chat
                this.writeInfo("Login \"" + login + "\" is already used.");
                communication.getEntree().close();
                communication.getSortie().close();
                communication.getSocket().close();
                this.communication = null;
            } else if (mess.getType() == Message.ACK_CONNECTION) { //
                infoTree.setNewName(this.getIdChat());
                // on reception la list des connecter au server
                communication.receiveMessage();

                for (TextTab tab : vectTextTab) {
                    tab.setConnection(communication); // TODO verification si les autre sont connecter
                    if (!tab.getIdTab().equals("systemPanel") && infoTree.getVectClient().contains(tab.getIdTab())) {
                        tab.setEnsable(true);
                    }
                }
                connectionMenuItem.setEnabled(false);
                newChannelMenuItem.setEnabled(true);
                deconnectionMenuItem.setEnabled(true);
                fileMenuItem.setEnabled(true);
                this.communication.start();
                this.writeInfo("Connection OK.");
            }
        } catch (Exception e) {
            this.writeInfo("Error in your parameters, hostname, num port...");
            System.out.println("error " + e.toString());
        }
    }

    /**
     * Methode appeller quand on veut fermer la communication ou
     * lors de coupure de connection.
     * Elle ferme la communication avec le server et change certains composant
     * graphique
     */
    @Action
    public void closeCommunication() {
        /**
         * si on est pas deconnecter, on previens le serveur qu'on vas le faire.
         * urgence > savoir si on doit prevenir le serveur ou pas.
         */
        if (communication != null) {
            if (communication.closeCommunication()) // on ferme le thread qui ecoute les entre
            {
                /**
                 * gestion de l'interface
                 */
                connectionMenuItem.setEnabled(true);
                deconnectionMenuItem.setEnabled(false);
                newChannelMenuItem.setEnabled(false);
                fileMenuItem.setEnabled(false);
                for (TextTab tab : vectTextTab) {
                    tab.setEnsable(false);
                }
                //   infoTree = new InfoTree(this, null);
            }
        }
    }

    /**
     * Si on veut fermer l'application, il faut clore la connection
     * Methode appeller par CTRL+Q ou par le menu File>Quit
     */
    @Action
    public void closeApplication() {
        try {
            //           System.out.println("hello bye");
            closeCommunication();
            System.exit(0); // fin de l'application client
        } catch (Exception e) {
        }
    }

    /**
     * Gestion des list Channel et User dans infoTree
     * @param mess Le message a dechiffrer
     */
    public void notifyList(Message mess) {
        if (mess.getType() == Message.DECONNECTION_CLIENT) {
            infoTree.removeClient(mess.getMessageStr());
            if (idTabExist(mess.getMessageStr())) {
                String listChannel = new String();
                for (String info : infoTree.getVectChannel()) {
                    listChannel += info + ";";
                }
                getTabClient(mess.getMessageStr()).writeMessage("\"" + mess.getMessageStr() + "\" is disconnected", "server");
                getTabClient(mess.getMessageStr()).setEnsable(false);
            }
            this.writeInfo("\"" + mess.getMessageStr() + "\" is disconnected");
        } else if (mess.getType() == Message.CONNECTION_CLIENT) {
            infoTree.newClient(mess.getMessageStr());
            if (idTabExist(mess.getMessageStr())) {
                getTabClient(mess.getMessageStr()).writeMessage("\"" + mess.getMessageStr() + "\" is conneted", "server");
                getTabClient(mess.getMessageStr()).setEnsable(true);
            }
            this.writeInfo("\"" + mess.getMessageStr() + "\" is conneted");
        } else if (mess.getType() == Message.NOTIFY_ADD_CHANNEL) {
            infoTree.newChannel(mess.getMessageStr());
            this.writeInfo("Channel \"" + mess.getMessageStr() + "\" has been created");
        } else if (mess.getType() == Message.NOTIFY_RM_CHANNEL) {
            infoTree.removeChannel(mess.getMessageStr());
            this.writeInfo("Channel \"" + mess.getMessageStr() + "\" has been deleted");
        } else if (!mess.getMessageStr().isEmpty()) {//if (mess.getType() == Message.LIST) {
            String[] tabSt;
            tabSt = mess.getMessageStr().split("-");
            HashSet<String> vectClient = new HashSet();
            HashSet<String> vectChannel = new HashSet();

            String[] tabSt_tmp = null;
            for (String id : tabSt) {
                tabSt_tmp = id.split(";");
                if (tabSt_tmp != null && tabSt_tmp[0].equals("CLIENT")) {
                    System.out.println(" client : " + tabSt_tmp[0]);
                    for (String idclient : tabSt_tmp) {
                        System.out.println(" id client : " + idclient);
                        if (!idclient.equals("CLIENT")) {
                            vectClient.add(idclient);
                        }
                    }
                } else if (tabSt_tmp != null && tabSt_tmp[0].equals("CHANNEL")) { // channel
                    for (String idchannel : tabSt_tmp) {
                        System.out.println(" id channel : " + idchannel);
                        if (!idchannel.equals("CHANNEL")) {
                            vectChannel.add(idchannel);
                        }
                    }
                }
            }
            infoTree.notifyList(vectClient, vectChannel);
            System.out.println("--------------FIN--");

        }
    }

    /**
     * Creation d'un nouveau chat si il n'existe pas
     * @param nom le nom du nouveau chat cad un channel ou un user
     * @param focus defini si le nouvelle onglet sera selectionner ou pas
     */
    public void newChat(String nom, boolean focus) {

        if (!idTabExist(nom) && communication != null) {
            TextTab newTab = new TextTab(this, communication, nom);
            tabPanel.addTab(nom, null, newTab, "Chat with " + nom);
            if (focus) {
                tabPanel.setSelectedComponent(newTab);
            }
            vectTextTab.add(newTab);
        } else if (idTabExist(nom)) {
            tabPanel.setSelectedComponent(this.getTabClient(nom));
        }
        if (infoTree.channelExist(nom)) {
            Message mess = new Message(Message.NEW_CLIENT_CHANNEL, this.getIdChat(), nom, "testfdg");
            try {
                mess.sendMessage(this.communication.getSortie());
            } catch (Exception e) {
                System.out.println("error closeclient" + e.toString());
            }
        }
    }


    /**
     * redirige le message sur le tab identifie par le destinataire du tab
     * @param mess le message a afficher
     */
    public void writeMessageTab(Message mess) {
        if (infoTree.channelExist(mess.getSrc())) {
            getTabClient(mess.getSrc()).writeMessage(mess.getMessageStr(), mess.getDest());
        } else {
            getTabClient(mess.getSrc()).writeMessage(mess.getMessageStr(), mess.getSrc());
        }
    }

    /**
     * Affiche des information directement sur le SystemPanel.
     * @param mess les informations a afficher
     */
    public void writeInfo(String mess) {
        getTabClient("systemPanel").writeMessage(mess, "server");
    }

    /**
     * recupere le tab d'identifiant de idTab
     * @param idTab
     * @return Le TextTab d'identifiant idTab s'il exsite
     * sinon renvoie null
     */
    public TextTab getTabClient(String idTab) {
        TextTab tabToReturn = null;
        for (TextTab textTab : vectTextTab) {
            if (idTab.equalsIgnoreCase(textTab.getIdTab())) {
                tabToReturn = textTab;
            }
        }
        return tabToReturn;
    }

    public String getIdChat() {
        return communication.getIdConnection();
    }

    public int getNumeroPort() {
        return numeroPort;
    }

    public void setNumeroPort(int numeroPort) {
        this.numeroPort = numeroPort;
    }

    public DownloadPanel getDownloadPanel() {
        return downloadPanel;
    }

    public void setDownloadPanel(DownloadPanel downloadPanel) {
        this.downloadPanel = downloadPanel;
    }

    /**
     * affiche des information sur les tabs ouvert!
     */
    public void displayTab() {
        for (TextTab tab : vectTextTab) {
            System.out.println("chat : " + tab.getIdTab() + ".");
        }
    }

    /**
     * Le tab selectionne
     * @return Le tab selectionne, null si aucun
     */
    public TextTab currentTab() {
        for (TextTab tab : vectTextTab) {
            if (tab.equals(this.tabPanel.getSelectedComponent())) { // && (!tab.getIdTab().equals("systemPanel"))
                return tab;
            }
        }
        return null;
    }

    /**
     * methode appeller par racourcie clavier ALT+ Pageup / Pagedown
     * Selectionne le tab suivant ou precedent suivant le sens
     * @param sens indique ci on est en UP ou en DOW
     */
    private void switchTab(String sens) {
        if (sens.equals("DOWN")) {
            if (tabPanel.getSelectedIndex() + 1 < tabPanel.getTabCount()) {
                tabPanel.setSelectedIndex(tabPanel.getSelectedIndex() + 1);
            } else {
                tabPanel.setSelectedIndex(0);
            }
        } else if (sens.equals("UP")) {
            if (tabPanel.getSelectedIndex() > 0) {
                tabPanel.setSelectedIndex(tabPanel.getSelectedIndex() - 1);
            } else {
                tabPanel.setSelectedIndex(tabPanel.getTabCount() - 1);
            }
        }
    }

    /**
     * Methode appelle par racourcie clavier CTRL+W
     * Si le tab que l'on veut fermer est un channel, alors on previens le server de la "deconnection"
     * @param tab le tab en question a supprimer
     */
    private void closeTab(TextTab tab) {
        if (infoTree.channelExist(tab.getIdTab())) { // c'est un channel
            Message mess = new Message(Message.RM_CLIENT_CHANNEL, this.getIdChat(), tab.getIdTab(), "testfdg");
            try {
                mess.sendMessage(this.communication.getSortie());
            } catch (Exception e) {
                System.out.println("error closeclient" + e.toString());
            }
        }
        tabPanel.remove(tab);
        vectTextTab.remove(tab);
    }

    /**
     * revois vrai si l'idTab exist
     * @param id L'identifiant du tab a verfier
     * @return vrai si le tab existe, faux sinon
     */
    public boolean idTabExist(String id) {
        boolean b = false;
        for (TextTab tab : vectTextTab) {
            if (id.equalsIgnoreCase(tab.getIdTab())) {
                b = true;
            }
        }
        return b;
    }

    /**
     * Recupere le sendFile d'identifiant id
     * @param id L'indentifiant du sendFile que l'on cherche
     * @return le sendFile s'il exste, null sinon
     */
    public SendFile getSendFile(String id) {
        for (SendFile sendFile : vectSendFile) {
            if (id.equalsIgnoreCase(sendFile.getLogin())) {
                return sendFile;
            }
        }
        return null;
    }

    public boolean isConnected() {
        return communication != null;
    }

    /**
     * Creation d'un nouveau channel de nom name
     * @param name le nom du nouveau channel
     */
    public void newChannel(String name) {
        Message mess = new Message(Message.ADD_CHANNEL, this.getIdChat(), "sytem", name);
        try {
            mess.sendMessage(this.communication.getSortie());
        } catch (Exception e) {
            System.out.println("error closeclient" + e.toString());
        }
        newChat(name, true);
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            aboutBox = new AboutBox(mainFrame);
        }
        aboutBox.setLocationRelativeTo(mainFrame);
        aboutBox.setVisible(true);
    }

    @Action
    public void showQuitBox() {
        if (quitBox == null) {
            quitBox = new DialogBox(this, mainFrame, true, "Do you really want to quit ?", "Quit Dialog", "quitApplication");
        }
        quitBox.setSize(400, 100); // besion, je ne sais pas pourquoi !
        quitBox.setLocationRelativeTo(mainFrame);
        quitBox.setVisible(true);
    }

    /**
     *
     */
    @Action
    public void showConnectionBox() {
        if (connectionBox == null) {
            connectionBox = new ConnectionBox(this, mainFrame, true);
        }
        connectionBox.setSize(280, 220); // besion, je ne sais pas pourquoi !
        connectionBox.setLocationRelativeTo(mainFrame);
        connectionBox.setVisible(true);
    }

    /**
     *
     */
    @Action
    public void showChannelBox() {
        if (newChannelBox == null) {
            newChannelBox = new NewChannelDialog(this, mainFrame, true);
        }
        newChannelBox.setLocationRelativeTo(mainFrame);
        newChannelBox.setVisible(true);
    }

    public Communication getCommunication() {
        return communication;
    }

    /**
     * Envoie d'un fichier a l'utilisateur du tab courant
     * Selection du ficher et creation de la connection sendFile
     */
    @Action
    public void showFileChooser() {

        if (!this.currentTab().getIdTab().equals("systemPanel")
                && !this.tabPanel.getSelectedComponent().equals(downloadPanel)
                && !infoTree.channelExist(this.currentTab().getIdTab())
                && infoTree.getVectClient().contains(this.currentTab().getIdTab())) {
            //On crée la fenetre qui va permettre de récupérer le chemin du fichier
            JFileChooser choix = new JFileChooser();
            choix.showOpenDialog(choix);

            String nomFichier = choix.getSelectedFile().getAbsolutePath();
            File file = new File(nomFichier);
            if (file.exists()) {
                SendFile sendFile = new SendFile(this, nomFichier, this.currentTab().getIdTab());
                vectSendFile.add(sendFile);
                sendFile.start();
            } else {
                this.writeInfo("file doesn't existe.");
            }
        } else {
            this.writeInfo("destination is current tab, select it (no channel, no systemPanel).");
        }
    }

    /**
     * Methode appelle par communication si on recois un message du type FILE
     * Demande confirmation d'envoie a l'utilisateur
     * Si refus, alors on previens l'envoyeur
     * Sinon, on demande le chemin ou l'on veut enregistrer le fichier
     * Creation de la connection avec sendFile
     * @param chaine la chaine d'information que contenait le message
     */
    public void sendFile(String chaine) {
        //on vient de récuperer des info d'une connexion
        //on récupère les infos
        String[] chaineCoupe;
        chaineCoupe = chaine.split(":");
        String login_ = chaineCoupe[0]; // le login, pour l'identifier
        String hostname_ = chaineCoupe[1]; // l'adresse du "server" pour l'envoie de fichier
        String port_ = chaineCoupe[2]; // le numero de port
        String nomFichier_ = chaineCoupe[3]; // le path du fichier!
        String sizeFile = chaineCoupe[4];


        receiveFileBox = new DialogBox(this, mainFrame, true, "Do you want to receive a file form : " + login_ + " ? \n " + nomFichier_, "Ask Dialog", "quitReceive");
        receiveFileBox.setSize(400, 100); // besion, je ne sais pas pourquoi !
        receiveFileBox.setLocationRelativeTo(mainFrame);
        receiveFileBox.setVisible(true);
        // dans receiveFileBox, si c'est ok on change la valeur de ackDialog dans client

        //on on crée une connexion avec ces informarions.
        if (this.ackDialog) {
            // on reinitialise ackDialog pour les prochaines utilisations
            JFileChooser choix = new JFileChooser();
            //  choix.getFileSystemView().createFileObject(nomFichier_+".cdsgs");
            choix.showOpenDialog(choix);
            // on recupere le chemin de l'emplacement pour recevoir le fichier
            String nomFichier = choix.getSelectedFile().getAbsolutePath();

            // on ackite pour l'autre, il se prepare a envoyer le fichier
            Message messageInfo = new Message(Message.FILEOK, getIdChat(), login_, login_);
            try {
                messageInfo.sendMessage(this.communication.getSortie());
            } catch (Exception e) {
                System.out.println("error closeclient" + e.toString());
            }

            // on creer l'envois de fichier, cad les connexion qui la compose
            SendFile sendFile = new SendFile(this, login_, hostname_, Integer.valueOf(port_), nomFichier, Long.valueOf(sizeFile));
            vectSendFile.add(sendFile);
            sendFile.start();

        } else {

            // si on veut pas, on retour un NON
            Message messageInfo = new Message(Message.FILE_NON, getIdChat(), login_, login_);
            try {
                messageInfo.sendMessage(this.communication.getSortie());
            } catch (Exception e) {
                System.out.println("error closeclient" + e.toString());
            }
        }
        this.ackDialog = false; // pour les prochaine utilisation
    }

    /**
     * Ajout d'un onglet de telechargement s'il n'existe pas
     * ajout d'une barre de progression au tab
     * @param text Le text a afficher enface de la bare de progression
     * @return la barre de progression pour la lier a sendFile (mise a jour de la progression)
     */
    public ProgressBar addDownloadProgressBar(String text) {
        if (downloadPanel == null) {
            downloadPanel = new DownloadPanel();
            tabPanel.addTab("Download", null, downloadPanel, "Download panel information");
        }
        ProgressBar pro = new ProgressBar(text);

        downloadPanel.addPB(pro);
        tabPanel.setSelectedComponent(downloadPanel);
        return pro;
    }

    /**
     * supprime le sendfile e du vecteur vectSendFile.
     * @param e le sendFile a supprimer
     */
    public void removeSendFile(SendFile e) {
        vectSendFile.remove(e);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jSplitPane1 = new javax.swing.JSplitPane();
        infoPanel = new javax.swing.JPanel();
        tabPanel = new javax.swing.JTabbedPane();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        connectionMenuItem = new javax.swing.JMenuItem();
        deconnectionMenuItem = new javax.swing.JMenuItem();
        newChannelMenuItem = new javax.swing.JMenuItem();
        fileMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBarre = new javax.swing.JProgressBar();

        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setOpaque(false);
        mainPanel.setLayout(new java.awt.BorderLayout());

        jSplitPane1.setName("jSplitPane1"); // NOI18N

        infoPanel.setName("infoPanel"); // NOI18N
        infoPanel.setOpaque(false);
        infoPanel.setLayout(new java.awt.BorderLayout());
        jSplitPane1.setLeftComponent(infoPanel);

        tabPanel.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        tabPanel.setTabPlacement(javax.swing.JTabbedPane.RIGHT);
        tabPanel.setAutoscrolls(true);
        tabPanel.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        tabPanel.setMinimumSize(new java.awt.Dimension(222, 333));
        tabPanel.setName("tabPanel"); // NOI18N
        tabPanel.setPreferredSize(new java.awt.Dimension(100, 10));
        tabPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tabPanelMouseClicked(evt);
            }
        });
        jSplitPane1.setRightComponent(tabPanel);

        mainPanel.add(jSplitPane1, java.awt.BorderLayout.CENTER);

        menuBar.setName("menuBar"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance().getContext().getResourceMap(ChatView.class);
        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance().getContext().getActionMap(ChatView.class, this);
        connectionMenuItem.setAction(actionMap.get("showConnectionBox")); // NOI18N
        connectionMenuItem.setName("connectionMenuItem"); // NOI18N
        fileMenu.add(connectionMenuItem);

        deconnectionMenuItem.setAction(actionMap.get("closeCommunication")); // NOI18N
        deconnectionMenuItem.setName("deconnectionMenuItem"); // NOI18N
        fileMenu.add(deconnectionMenuItem);

        newChannelMenuItem.setAction(actionMap.get("showChannelBox")); // NOI18N
        newChannelMenuItem.setName("newChannelMenuItem"); // NOI18N
        fileMenu.add(newChannelMenuItem);

        fileMenuItem.setAction(actionMap.get("showFileChooser")); // NOI18N
        fileMenuItem.setName("fileMenuItem"); // NOI18N
        fileMenu.add(fileMenuItem);

        exitMenuItem.setAction(actionMap.get("showQuitBox")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        exitMenuItem.setPreferredSize(new java.awt.Dimension(121, 19));
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setMinimumSize(new java.awt.Dimension(100, 100));
        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBarre.setName("progressBarre"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 265, Short.MAX_VALUE)
                .addComponent(progressBarre, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBarre, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    private void tabPanelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tabPanelMouseClicked
    }//GEN-LAST:event_tabPanelMouseClicked

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        // TODO add your handling code here:
}//GEN-LAST:event_exitMenuItemActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem connectionMenuItem;
    private javax.swing.JMenuItem deconnectionMenuItem;
    private javax.swing.JMenuItem fileMenuItem;
    private javax.swing.JPanel infoPanel;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem newChannelMenuItem;
    private javax.swing.JProgressBar progressBarre;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JSeparator statusPanelSeparator;
    private javax.swing.JTabbedPane tabPanel;
    // End of variables declaration//GEN-END:variables
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;
    private JDialog connectionBox;
    private JDialog quitBox;
    private JDialog errorBox;
    private JDialog newChannelBox;
    private JDialog receiveFileBox;

    public boolean isAckDialog() {
        return ackDialog;
    }
    public void setAckDialog(boolean ackDialog) {
        this.ackDialog = ackDialog;
    }
}
